package com.huluobo.a2206douyindemo.utils;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import androidx.annotation.NonNull;

import kotlin.jvm.internal.PropertyReference0;

/**
 * Created by LC on 2024/8/30.
 * 贝塞尔曲线View,通过2个偏移量来控制曲线的弧度
 */
public class BezierLineAnimView extends RelativeLayout {
    private int[] ids;

    public void setIds(int[] ids) {
        this.ids = ids;
    }

    public BezierLineAnimView(Context context) {
        super(context);
    }

    public BezierLineAnimView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void addFavor() {
        //1.创建一个ImageView添加到当前布局上
        ImageView animView = new ImageView(getContext());
        int index = (int) (Math.random() * ids.length);//随机生成一个下标,用于控制心形图标的颜色
        animView.setImageResource(ids[index]);

        LayoutParams params = new LayoutParams(200, 200);
        animView.setLayoutParams(params);
        addView(animView);

        //2.定义起始点和控制点
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        float offset = 100;//当前ImageView一半的大小

        //定义起始坐标点
        PointF P0 = new PointF(width / 2.0f - offset, height);//起点位置
        PointF P3 = new PointF(width / 2.0f - offset, 0);//终点

        //定义控制点(使用随机数随机赋值控制点,可以修改曲线的曲率)
        PointF P1 = new PointF((float) (Math.random() * width) - offset, height / 3.0f * 2 - offset);
        PointF P2 = new PointF((float) (Math.random() * width) - offset, height / 3.0f - offset);

        //3.设置属性动画
        ValueAnimator valueAnimator = ValueAnimator.ofObject(new BezierTypeEvaluator(P1, P2), P0, P3);
        valueAnimator.setDuration(1200);
        valueAnimator.setInterpolator(new AccelerateInterpolator());
        valueAnimator.addUpdateListener(animation -> {
            PointF pointF = (PointF) animation.getAnimatedValue();
            animView.setX(pointF.x);//修改x轴的轨迹坐标
            animView.setY(pointF.y);//修改y轴的轨迹坐标
            float f = animation.getAnimatedFraction();
            animView.setAlpha(1 - f);
        });

        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                removeView(animView);
            }
        });
        
        valueAnimator.start();

    }

    //鉴别器,相当于一个曲线公式,体现的是一个动画移动轨迹
    class BezierTypeEvaluator implements TypeEvaluator<PointF> {
        PointF P1, P2;//代表曲线拉伸的点,偏移量

        public BezierTypeEvaluator(PointF p1, PointF p2) {
            P1 = p1;
            P2 = p2;
        }

        @Override
        public PointF evaluate(float fraction, PointF P0, PointF P3) {
            PointF P = new PointF();//声明移动轨迹

            //三阶贝塞尔曲线计算公式
            P.x = P0.x * (1 - fraction) * (1 - fraction) * (1 - fraction)
                    + 3 * P1.x * fraction * (1 - fraction) * (1 - fraction)
                    + 3 * P2.x * fraction * fraction * (1 - fraction)
                    + P3.x * fraction * fraction * fraction;

            P.y = P0.y * (1 - fraction) * (1 - fraction) * (1 - fraction)
                    + 3 * P1.y * fraction * (1 - fraction) * (1 - fraction)
                    + 3 * P2.y * fraction * fraction * (1 - fraction)
                    + P3.y * fraction * fraction * fraction;

//            //二阶贝塞尔曲线公式
//            P.x = P0.x * (1 - fraction) * (1 - fraction)
//                    + 2 * P1.x * fraction * (1 - fraction)
//                    + P3.x * fraction * fraction;
//
//            //一阶贝塞尔曲线公式
//            P.x = P0.x * (1 - fraction)
//                    + P3.x * fraction;
//
//            //四阶贝塞尔曲线公式
//            P.x = P0.x * (1 - fraction) * (1 - fraction) * (1 - fraction) * (1 - fraction)
//                    + 4 * P1.x * fraction * (1 - fraction) * (1 - fraction) * (1 - fraction)
//                    + 4 * P2.x * fraction * fraction * (1 - fraction) * (1 - fraction)
//                    + 4 * P3.x * fraction * fraction * fraction * (1 - fraction)
//                    + P4.x * fraction * fraction * fraction * fraction''

            return P;
        }
    }
}
